<script setup>
import { ref, onMounted, nextTick, computed } from 'vue';
import { DataSet, Network } from "vis-network/standalone/umd/vis-network.min.js"; // 引入Vis.js
import { Graph } from '@/utils/graph';
import { ElMessage } from 'element-plus';
const cityData = ref([]);

const edges = ref([]);
getData()
function getData() {
    const city = localStorage.getItem("CITY_DATA")
    if (!city) {
        cityData.value = [
            { id: "1", label: "北京" },
            { id: "2", label: "天津" },
            { id: "3", label: "上海" },
            { id: "4", label: "郑州" },
            { id: "5", label: "南昌" },
            { id: "6", label: "广州" },
            { id: "7", label: "株洲" },
            { id: "8", label: "贵阳" },
            { id: "9", label: "重庆" },
            { id: "10", label: "兰州" },
            { id: "11", label: "西宁" },
            { id: "12", label: "成都" },
            { id: "13", label: "昆明" },
            { id: "14", label: "西安" },
            { id: "15", label: "武汉" },
            { id: "16", label: "长沙" },
        ]
        localStorage.setItem("CITY_DATA",JSON.stringify(cityData.value))
    } else {
        cityData.value = JSON.parse(city)
    }
    const edge = localStorage.getItem("EDGE_DATA")
    if (!edge) {
        edges.value = [
            // 北京相关连接，构建多种成本、时间、中转情况的路径起点
            { from: "1", to: "2", cost: 100, time: 20, departureTime: "08:00" },
            { from: "1", to: "3", cost: 1770, time: 50, departureTime: "09:00" },
            { from: "1", to: "4", cost: 50, time: 60, departureTime: "15:00" },
            { from: "1", to: "14", cost: 40, time: 60, departureTime: "08:30" },
            { from: "1", to: "15", cost: 20, time: 90, departureTime: "09:30" },

            // 天津相关连接，延伸路径
            { from: "2", to: "3", cost: 15, time: 25, departureTime: "08:00" },
            { from: "2", to: "4", cost: 15, time: 25, departureTime: "10:00" },
            { from: "2", to: "5", cost: 30, time: 10, departureTime: "11:00" },
            { from: "2", to: "3", cost: 40, time: 60, departureTime: "17:00" },

            // 上海相关连接，拓展路径并构建不同成本、时间组合
            { from: "3", to: "2", cost: 20, time: 30, departureTime: "12:00" },
            { from: "3", to: "4", cost: 20, time: 30, departureTime: "12:00" },
            { from: "3", to: "5", cost: 25, time: 35, departureTime: "13:00" },
            { from: "3", to: "6", cost: 40, time: 40, departureTime: "18:00" },

            // 郑州相关连接，继续串联
            { from: "4", to: "5", cost: 5, time: 10, departureTime: "14:00" },
            { from: "4", to: "14", cost: 30, time: 50, departureTime: "15:00" },

            // 南昌相关连接
            { from: "5", to: "6", cost: 30, time: 40, departureTime: "18:00" },
            { from: "5", to: "15", cost: 25, time: 50, departureTime: "19:00" },

            // 广州相关连接，构建不同中转情况的后续路径
            { from: "6", to: "7", cost: 10, time: 15, departureTime: "19:00" },
            { from: "6", to: "16", cost: 20, time: 30, departureTime: "20:00" },

            // 株洲相关连接
            { from: "7", to: "8", cost: 25, time: 45, departureTime: "20:00" },

            // 贵阳相关连接
            { from: "8", to: "9", cost: 20, time: 30, departureTime: "21:00" },
            { from: "8", to: "13", cost: 30, time: 50, departureTime: "22:00" },

            // 重庆相关连接
            { from: "9", to: "10", cost: 50, time: 60, departureTime: "22:00" },
            { from: "9", to: "12", cost: 40, time: 50, departureTime: "23:00" },

            // 兰州相关连接
            { from: "10", to: "11", cost: 40, time: 55, departureTime: "23:00" },

            // 其他城市之间的连接，完善全图连接并体现不同策略差异
            { from: "12", to: "13", cost: 50, time: 90, departureTime: "01:00" },
            { from: "13", to: "14", cost: 40, time: 80, departureTime: "02:00" },
            { from: "14", to: "15", cost: 30, time: 70, departureTime: "03:00" },
            { from: "15", to: "16", cost: 25, time: 60, departureTime: "04:00" },
        ]
        localStorage.setItem("EDGE_DATA",JSON.stringify(edges.value))
    } else {
        edges.value = JSON.parse(edge)
    }
}
// 显示地图的实例
const display = ref(null);

const options = {
    nodes: {
        size: 40, // 设置节点大小
        font: {
            size: 30, // 设置节点标签字体大小
        },
    },
    edges: {
        color: {
            color: "#848484", // 默认边颜色
            highlight: "#7d56c1", // 高亮边颜色
        },
        width: 3, // 设置边的宽度
        selectionWidth: 5, // 新增属性，用于设置高亮边的宽度
        arrows: {
            to: { 
                enabled: true, 
                scaleFactor: 0.5 // 设置箭头的大小
            },
        },
    },
    
    physics: {
        enabled: true, // 启用物理引擎
        barnesHut: {
            gravitationalConstant: -10000, 
            centralGravity: 0.3, // 节点之间的引力
            springLength: 300, // 设定边的默认长度
            springConstant: 0.04, // 设置弹簧的弹性系数
        },
        stabilization: {
            enabled: true, // 启用物理引擎稳定
            iterations: 1000, // 设定稳定的迭代次数
            updateInterval: 25, // 设定更新间隔
        },
    },
    layout: {
        randomSeed: 2, // 可以设置布局的随机种子
    },
    interaction: {
        selectable: false, // 允许选择边和节点
        selectConnectedEdges: false, // 是否选择与节点连接的边
        dragNodes: false, // 禁用节点拖动功能
        dragView: false, // 禁用区域拖动功能
        zoomView: false, // 禁用放大缩小
    },
};
//网络图
let network = null
// 初始化网络图
onMounted(() => {
    network = new Network(display.value, {
        nodes: new DataSet(cityData.value), 
        edges: new DataSet(edges.value)
    }, options);
});


const path = ref([])
const selectOrigin = ref('');
const selectDest = ref('');
const strategy = ref('1');
const strategyList = [
    'time','cost','transfers'
]
const graph = new Graph(edges.value);



// 点击进行规划
const handleArrange = () => {
    network.selectEdges([])
    if (selectOrigin.value === '' || selectDest.value === '') {
        ElMessage.error('请选择起点和终点');
        return;
    }
    if (selectDest.value === selectOrigin.value) {
        ElMessage.error('起点和终点不能一致');
        return;
    }

    const numStrategy = parseInt(strategy.value);
    let result = null;
    if (numStrategy === 1) {
        // 时间优先
        result = graph.dijkstra(selectOrigin.value, selectDest.value, 'time');
        console.log("时间优先路径:", result);
    } else if (numStrategy === 2) {
        // 价格优先
        result = graph.dijkstra(selectOrigin.value, selectDest.value, 'cost');
        console.log("价格优先路径:", result);
    } else if (numStrategy === 3) {
        // 中转次数优先
        result = graph.dijkstra(selectOrigin.value, selectDest.value, 'transfers');
        console.log("中转次数优先路径:", result);
    }

    if (result === null) {
        ElMessage.error('没有路线')
        return
    }
    if (result) {
        highlightPath(result);
        path.value = []
        console.log(result);
        
        result.pathEdges.forEach((edge) => {
            const src = cityData.value.find((item) => {
                return item.id === edge.from
            }).label
            const dest = cityData.value.find((item) => {
                return item.id === edge.to
            }).label
            const cost = edge.cost
            const departureTime = edge.departureTime
            const time = edge.time
            const arriveTime = calculateArrivalTimeCorrected(departureTime, edge.time)
            path.value.push({
                src,dest,cost,departureTime,arriveTime,time
            })
            console.log(path.value);
            
        })
        
    }
};

const calculateArrivalTimeCorrected = (departureTimeStr, durationMinutes) => {

    const [departureHours, departureMinutes] = departureTimeStr.split(':').map(Number);
    
 
    const departureDate = new Date();
    departureDate.setHours(departureHours, departureMinutes, 0, 0); // 设置小时、分钟、秒和毫秒为0
    

    const durationMs = durationMinutes * 60 * 1000;
    departureDate.setTime(departureDate.getTime() + durationMs);
    const arrivalHours = departureDate.getHours().toString().padStart(2, '0');
    const arrivalMinutes = departureDate.getMinutes().toString().padStart(2, '0');
    return `${arrivalHours}:${arrivalMinutes}`;
}
 
// 高亮路径函数
const highlightPath = (result) => {
    const ids = []
    result.pathEdges.forEach((res) => {
        const edge = edges.value.find((item) => {
            return item.from === res.from && item.to === res.to
        })
        ids.push(edge.id)
    })

    network.selectEdges(ids)
};

const totalCost = computed(() => {
    return path.value.reduce((prev,item) => prev+item.cost,0)
})

const totalTime = computed(() => {
    console.log(path.value,path.value.departureTime,path.value.arriveTime);
    
    return calculateTimeDifferenceInMinutes(path.value[0].departureTime,path.value[path.value.length-1].arriveTime)
})

// 计算时间差
const calculateTimeDifferenceInMinutes = (startTime, endTime) => {
    const start = new Date(`1970-01-01T${startTime}:00Z`); // 使用 UTC 时间并添加 ':00' 秒
    const end = new Date(`1970-01-01T${endTime}:00Z`);
    const differenceInMilliseconds = end - start;

    const differenceInMinutes = differenceInMilliseconds / (1000 * 60);
 

    return differenceInMinutes;
}
</script>

<template>
    <div class="user_page_container">
        <div class="left">
            <div class="inp">
                <div class="inp_item">
                    <el-select
                        v-model="selectOrigin"
                        placeholder="选择起点"
                        size="large"
                        style="width: 240px"
                    >
                        <el-option
                            v-for="item in cityData"
                            :key="item.id"
                            :label="item.label"
                            :value="item.id"
                        />
                    </el-select>
                    <el-select
                        style="margin-left: 20px; width: 240px"
                        v-model="selectDest"
                        placeholder="选择终点"
                        size="large"
                    >
                        <el-option
                            v-for="item in cityData"
                            :key="item.id"
                            :label="item.label"
                            :value="item.id"
                        />
                    </el-select>
                </div>
                <div class="inp_item">
                    <el-radio-group v-model="strategy">
                        <el-radio value="1">时间优先</el-radio>
                        <el-radio value="2">价格优先</el-radio>
                        <el-radio value="3">中转次数优先</el-radio>
                    </el-radio-group>
                </div>
                <div class="inp_item" @click="handleArrange()">
                    <el-button size="large">进行规划</el-button>
                </div>
            </div>
            <div class="arrangement_show">
                <div class="show_item" v-for="(item,index) in path" :key="index">
                    <div class="src">
                        <div class="time">{{ item.departureTime }}</div>
                        <div class="city">{{ item.src }}</div>
                    </div>
                    <div class="arrow">
                        <img src="@/assets/imgs/arrow.png" alt="">
                    </div>
                    <div class="dest">
                        <div class="time">{{ item.arriveTime }}</div>
                        <div class="city">{{ item.dest }}</div>
                    </div>
                    <div class="cost">
                        ￥{{ item.cost }}
                    </div>
                </div>
                <div class="total_show" v-if="path && path.length > 0">
                    <div class="total_cost">
                        <span>总花费￥{{ totalCost }}</span>
                    </div>
                    <div class="total_time">
                        <span>总耗时{{ totalTime }}分钟</span>
                    </div>
                    <div class="total_transfer">
                        <span>中转次数{{ path.length-1 }}</span>

                    </div>
                </div>
            </div>
        </div>
        <div class="right">
            <div class="display" ref="display"></div>
        </div>
    </div>
</template>

<style scoped lang="less">
.user_page_container {
    width: 100%;
    height: 100%;
    padding: 30px;
    display: flex;
}
.left,.right {
    width: 50%;
    height: 100%;
}

.inp {
    width: 100%;
    height: 30%;
}

.inp_item {
    margin-top: 20px;
}

.display {
    width: 100%;
    height: 100%;
}
.arrangement_show {
    height: 70%;
    width: 100%;
    overflow: scroll;
}

.show_item {
    display: flex;
    width: 100%;
    margin-top: 10px;
}
.cost {
    font-size: 20px;
    color: #f05a55;
    margin-left: 30px;
}
.time {
    font-size: 16px
}
.city {
    font-size: 14px;
    color: #d4d2d5;
}
.total_show {
    display: flex;
    width: 70%;
    margin: 20px auto;
    justify-content: space-between;
}

</style>
